package com.nox.trademe.testapp.fragments;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import com.nox.trademe.testapp.MainActivity;
import com.nox.trademe.testapp.R;
import com.nox.trademe.testapp.adapters.MainCategoryAdapter;
import com.nox.trademe.testapp.models.MainCategory;
import com.nox.trademe.testapp.models.Subcategory;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class ListMainCategoriesFragment extends Fragment {

	public static final String TAG = "ListMainCategoriesFragment";
	private ArrayList<MainCategory> categoryList = new ArrayList<MainCategory>();
	private MainCategoryAdapter adapter;
	private ListView categoryListView;
	private Activity activity;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		Log.v(TAG, "Activity State: onCreate()");
		super.onCreate(savedInstanceState);
	}

	@Override
	public void onAttach(Activity activity) {
		Log.v(TAG, "Activity State: onAttach()");
		// Check if activity implements CategoryListener interface
		if (!(activity instanceof CategoryListener))
			throw new ClassCastException();
		this.activity = activity;
		super.onAttach(activity);
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		Log.v(TAG, "Activity State: onCreateView()");
		View view = inflater.inflate(R.layout.fragment_maincategories, container, true);
		categoryListView = (ListView) view.findViewById(R.id.maincategory_list);
		adapter = new MainCategoryAdapter(categoryList,	getActivity());
		categoryListView.setAdapter(adapter);
		categoryListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
				((CategoryListener) getActivity()).onChangeCategory(categoryList.get(position), true);
				}
			});
		setHasOptionsMenu(false);

		(new AsyncListViewLoader()).execute("http://api.trademe.co.nz/v1/Categories.json?with_counts=true");
		Log.v(TAG, "Activity State: onCreateView() finished");
		return view;
	}

	private class AsyncListViewLoader extends AsyncTask<String, Void, List<MainCategory>> {
		public static final String TAG = "AsyncListViewLoader";
		private final CustomProgressDialogFragment dialog;

        private AsyncListViewLoader() {
            dialog = new CustomProgressDialogFragment();
        }

        @Override
		protected void onPostExecute(List<MainCategory> result) {
			Log.v(TAG, "Activity State: onPostExecute()");
			super.onPostExecute(result);
			dialog.dismiss();
			adapter.notifyDataSetChanged();
            ((MainActivity)activity).onChangeCategory(result.get(0), false);
		}

		@Override
		protected void onPreExecute() {
			Log.v(TAG, "Activity State: onPreExecute()");
			super.onPreExecute();
			dialog.show(getActivity().getSupportFragmentManager(), TAG);
		}

		@Override
		protected List<MainCategory> doInBackground(String... params) {

			Log.v(TAG, "Activity State: doInBackground()");
			
			try {
				URL u = new URL(params[0]);

				HttpURLConnection connection = (HttpURLConnection) u
						.openConnection();
				connection.setRequestMethod("GET");

				connection.connect();
				int statusCode = connection.getResponseCode();
				if (statusCode != HttpURLConnection.HTTP_OK) {
					Log.e(TAG, "Invalid Response Code: " + statusCode);
					Log.e(TAG,
							"GET Response Message: "
									+ connection.getResponseMessage());
					return categoryList;
				} else {
					Log.v(TAG, "Main Category list received");
					Log.d(TAG,
							"GET Response Message: "
									+ connection.getResponseMessage());
					BufferedReader br = new BufferedReader(
							new InputStreamReader(connection.getInputStream()));
					StringBuilder sb = new StringBuilder();
					String line;
					while ((line = br.readLine()) != null) {
						sb.append(line + "\n");
					}
					br.close();
					try {
						JSONObject response = new JSONObject(sb.toString());
						//Log.d(TAG, "Response stream: " + response.toString());
						JSONArray mainCategoriesArray = response.getJSONArray("Subcategories");
						//Log.d(TAG, "Categories stream: " + mainCategoriesArray.toString());
						for (int i = 0; i < mainCategoriesArray.length(); i++) {
							//Log.d(TAG, "Adding Category from stream : " + mainCategoriesArray.getJSONObject(i).toString());
							categoryList.add(convertJSONObjectToMainCategory(mainCategoriesArray.getJSONObject(i)));
						}
					} catch (JSONException e) {
						Log.e(TAG, "Failed to parse JSON.", e);
					}
				}
				connection.disconnect();
			} catch (Throwable t) {
				t.printStackTrace();
			}
			return categoryList;
		}

		private MainCategory convertJSONObjectToMainCategory(JSONObject obj) throws JSONException {
			String name = obj.getString("Name");
			String number = obj.getString("Number");
			String path = obj.getString("Path");
            ArrayList<Subcategory> list = new ArrayList<Subcategory>();
            if (obj.has("Subcategories")) {
                JSONArray subcategoriesArray = obj.getJSONArray("Subcategories");
                if (subcategoriesArray != null) {
                    for (int i = 0; i < subcategoriesArray.length(); i++) {
                        list.add(convertJSONObjectToSubcategory(subcategoriesArray.getJSONObject(i)));
                        }
                    }
                }
			return new MainCategory(name, number, path, list);
		}
        private Subcategory convertJSONObjectToSubcategory(JSONObject obj) throws JSONException {
            String name = obj.getString("Name");
            String number = obj.getString("Number");
            String path = obj.getString("Path");
            String count = new String("0");
            ArrayList<Subcategory> list = new ArrayList<Subcategory>();
            if (obj.has("Count")) {
                count = obj.getString("Count");
                if (obj.has("Subcategories")) {
                    JSONArray subcategoriesArray = obj.getJSONArray("Subcategories");
                    if (subcategoriesArray != null) {
                        for (int i = 0; i < subcategoriesArray.length(); i++) {
                            list.add(convertJSONObjectToSubcategory(subcategoriesArray.getJSONObject(i)));
                        }
                    }
                }
            }
            return new Subcategory(name, number, path, count, list);
        }
	}

	public interface CategoryListener {
		public void onChangeCategory(MainCategory category, boolean closePane);
	}
}
